/*
*	File: Matrix.cpp
*	Date: 12/06/2011
*	Author: Ivan Gao
*	Desc:
*/
#include "Matrix.h"

SMatrix3x3::SMatrix3x3 () : _11 (1.0f), _12 (0.0f), _13 (0.0f),
							_21 (0.0f), _22 (1.0f), _23 (0.0f),
							_31 (0.0f), _32 (0.0f), _33 (1.0f)
{

}

SMatrix3x3::SMatrix3x3 (float _f11, float _f12, float _f13, float _f21, float _f22, float _f23, float _f31, float _f32, float _f33) :
_11 (_f11), _12 (_f12), _13 (_f13), _21 (_f21), _22 (_f22), _23 (_f23), _31 (_f31), _32 (_f32), _33 (_f33)
{

}

SMatrix3x3::SMatrix3x3 (const SMatrix3x3 & rMtx)
{
	memcpy (v, rMtx.v, sizeof (rMtx.v));
}

SMatrix3x3::SMatrix3x3 (float weight, const SMatrix3x3 & rMtx)
{
	_11 = rMtx._11 * weight; _12 = rMtx._12 * weight; _13 = rMtx._13 * weight;
	_21 = rMtx._21 * weight; _22 = rMtx._22 * weight; _23 = rMtx._23 * weight;
	_31 = rMtx._31 * weight; _32 = rMtx._32 * weight; _33 = rMtx._33 * weight;
}

// Assume rQua is a unit quaternion.
SMatrix3x3::SMatrix3x3 (const SQuaternion & rQua)
{
	*this = rQua;
}

SMatrix3x3 & SMatrix3x3::operator = (const SQuaternion & rQua)
{
	float xx2 = rQua.x * rQua.x * 2.0f;
	float yy2 = rQua.y * rQua.y * 2.0f;
	float zz2 = rQua.z * rQua.z * 2.0f;
	float xy2 = rQua.x * rQua.y * 2.0f;
	float zw2 = rQua.z * rQua.w * 2.0f;
	float xz2 = rQua.x * rQua.z * 2.0f;
	float yw2 = rQua.y * rQua.w * 2.0f;
	float yz2 = rQua.y * rQua.z * 2.0f;
	float xw2 = rQua.x * rQua.w * 2.0f;
	_11 = 1.0f - yy2 - zz2;		_12 = xy2 - zw2;			_13 = xz2 + yw2;
	_21 = xy2 + zw2;			_22 = 1.0f - xx2 - zz2;		_23 = yz2 - xw2;
	_31 = xz2 - yw2;			_32 = yz2 + xw2;			_33 = 1.0f - xx2 - yy2;
	return *this;
}

SMatrix3x3::~SMatrix3x3 ()
{

}

SMatrix3x3 & SMatrix3x3::operator = (const SMatrix3x3 & rQua)
{
	memcpy (v, rQua.v, sizeof (v));
	return *this;
}

SMatrix3x3 & SMatrix3x3::operator *= (const SMatrix3x3 & m)
{
	float f[9];
	f[0] = _11 * m._11 + _12 * m._21 + _13 * m._31;
	f[1] = _11 * m._12 + _12 * m._22 + _13 * m._32;
	f[2] = _11 * m._13 + _12 * m._23 + _13 * m._33;

	f[3] = _21 * m._11 + _22 * m._21 + _23 * m._31;
	f[4] = _21 * m._12 + _22 * m._22 + _23 * m._32;
	f[5] = _21 * m._13 + _22 * m._23 + _23 * m._33;

	f[6] = _31 * m._11 + _32 * m._21 + _33 * m._31;
	f[7] = _31 * m._12 + _32 * m._22 + _33 * m._32;
	f[8] = _31 * m._13 + _32 * m._23 + _33 * m._33;
	memcpy (v, f, sizeof (v));
	return *this;
}

SMatrix3x3 & SMatrix3x3::operator *= (float scale)
{
	_11 *= scale;
	_12 *= scale;
	_13 *= scale;

	_21 *= scale;
	_22 *= scale;
	_23 *= scale;

	_31 *= scale;
	_32 *= scale;
	_33 *= scale;
	return *this;
}

float SMatrix3x3::Determinant () const
{
	float det = _22 * (_11 * _33 - _13 * _31) + 
		_32 * (_13 * _21 - _11 * _23) +
		_12 * (_31 * _23 - _33 * _21);
	return det;
} // Determinant




